<?php
/**
 * DMFramework
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @url http://dmframework.nl
 */

/**
 * The directory class can be used to get a file list and staticcly create
 * files and directory objects.
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @package System.Library
 */
class Dmf_Directory
{
    /**
     * The full filename
     * 
     * @var string 
     */
    private $_filename;
    
    /**
     * Pathinfo -> Basename
     *  
     * @var string 
     */
    public $basename;
    
    /**
     * Pathinfo -> Dirname
     * 
     * @var string 
     */
    public $dirname;
    
    /**
     * Pathinfo -> Filename
     * 
     * @var string 
     */
    public $filename;
    
    /**
     * Constructor
     * 
     * @param string $filename 
     */
    public function __construct( $filename )
    {
        if ( ! is_dir( $filename ) )
        {
            @mkdir( $filename );
        }
        
        $this->_filename = realpath( $filename );
        $pathinfo = pathinfo( $filename );
        
        $this->basename = $pathinfo['basename'];
        $this->dirname = $pathinfo['dirname'];
        $this->filename = $pathinfo['filename'];
        $this->filepath = realpath( $filename );
    }
    
    public static function file( $file )
    {
        $obj = new Dmf_File( $file );
        
        return $obj;
    }
    
    public static function directory( $file )
    {
        $obj = new Dmf_Directory( $file );
        
        return $obj;
    }
    
    /**
     * Chmod a directory (not recursive).
     * 
     * @param float $rights
     * @return boolean 
     */
    public function chmod( $rights )
    {
        $rights = ( substr( $rights, 0, 1 ) == '0' || substr( $rights, 0, 1 ) == '1' ) ? $rights : '0' . $rights;
        
        if ( chmod( $this->_filename, octdec( $rights ) ) )
        {
            $this->__construct( $this->_filename );
            
            return true;
        }
        
        return false;
    }
    
    /**
     * Copy this directory to another
     * 
     * @param string $to
     * @param mixed $from
     * @param mixed $dir 
     */
    public function copy( $to, $from = false, $dir = false )
    {
        $info = pathinfo( $this->_filename );
        $dir  = ( $dir === false && $from == false )  ? $info['basename'] : $dir;
        $from = ( $from === false ) ? $this->_filename : $from;
        
        if ( $dir !== false ) mkdir( $to . '/' . $dir . '/' );
        if ( ! is_dir( $to ) ) mkdir( $to );
        
        foreach ( scandir( $from ) as $item )
        {
            if ( $item == '.' || $item == '..' ) continue;
            
            if ( is_dir( $from . '/' . $item ) )
            {
                $this->copy( $to . '/' . $dir . '/' . $item, $from . '/' . $item );
            }
            else
            {
                copy( $from . '/' . $item, $to . '/' . $dir . '/' . $item );
            }
        }
    }
    
    /**
     * Move this directory to another directory.
     * 
     * @param string $to
     * @param mixed $from
     * @param mixed $dir
     */
    public function move( $to, $from = false, $dir = false )
    {
        $info = pathinfo( $this->_filename );
        $dir  = ( $dir === false && $from == false )  ? $info['basename'] : $dir;
        $from = ( $from === false ) ? $this->_filename : $from;
        
        if ( $dir !== false ) mkdir( $to . '/' . $dir . '/' );
        if ( ! is_dir( $to ) ) mkdir( $to );
        
        foreach ( scandir( $from ) as $item )
        {
            if ( $item == '.' || $item == '..' ) continue;
            
            if ( is_dir( $from . '/' . $item ) )
            {
                $this->move( $to . '/' . $dir . '/' . $item, $from . '/' . $item );
            }
            else
            {
                copy( $from . '/' . $item, $to . '/' . $dir . '/' . $item );
                
                unlink( $from . '/' . $item );
            }
        }
        
        rmdir( $from );
    }
    
    /**
     * Rename a Directory
     * 
     * @param string $newname
     * @return boolean 
     */
    public function rename( $newname )
    {
        if ( rename( $this->_filename, $this->dirname . '/' . $newname ) )
        {
            $this->__construct( $this->dirname . '/' . $newname );
            
            return true;
        }
        
        return false;
    }
    
    /**
     * Shortcut to Dmf_Files -> getFiles()
     * 
     * @return array 
     */
    public function getFiles()
    {
        $files = new Dmf_Files();
        
        return $files->getFiles( $this->_filename );
    }
    
    /**
     * Shortcut to Dmf_Files -> getList()
     * 
     * @return array 
     */
    public function getList()
    {
        $files = new Dmf_Files();
        
        return $files->getList( $this->_filename );
    }
    
    /**
     * Recursive delete a directory
     * Shortcut to Dmf_Files -> delete() 
     */
    public function delete( $dir = false )
    {
        $dir = ( $dir === false ) ? $this->_filename : $dir;
        
        if ( ! file_exists( $dir ) )
        {
            return true;
        }
        
        if ( ! is_dir( $dir ) ) 
        {
            return unlink( $dir );
        }
        
        foreach ( scandir( $dir ) as $item )
        {
            if ( $item == '.' || $item == '..' ) continue;
            
            $this->delete( $dir . '/' . $item );
        }
            
        return rmdir( $dir );
    }
}